package com.lineage.server.datatables;

import com.lineage.DatabaseFactoryLogin;
import com.lineage.config.Config;
import com.lineage.server.templates.DeClan;
import com.lineage.server.templates.DeName;
import com.lineage.server.utils.SQLUtil;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Random;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class DeNameTable {
  private static final Log _log = LogFactory.getLog(DeNameTable.class);
  
  private static final Map<String, DeName> _denameList = new HashMap<>();
  
  private static final Map<Integer, DeName> _denames = new HashMap<>();
  
  private static DeNameTable _instance;
  
  private static boolean _reclanInfo = false;
  
  private static final Random _random = new Random();
  
  public static DeNameTable get() {
    if (_instance == null)
      _instance = new DeNameTable(); 
    return _instance;
  }
  
  public void load() {
    Connection con = null;
    PreparedStatement pstm = null;
    ResultSet rs = null;
    try {
      con = DatabaseFactoryLogin.get().getConnection();
      pstm = con.prepareStatement("SELECT * FROM `de_name`");
      rs = pstm.executeQuery();
      while (rs.next()) {
        int deobjid = rs.getInt("deobjid");
        String name = "";
        if (Config.CLIENT_LANGUAGE == 3) {
          name = rs.getString("denamebig5");
        } else {
          name = rs.getString("dename");
        } 
        int type = rs.getInt("type");
        int sex = rs.getInt("sex");
        int clanid = rs.getInt("clanid");
        DeName deName = new DeName(deobjid, name, type, sex, clanid);
        if (_denameList.get(name) == null) {
          _denameList.put(name, deName);
          _denames.put(Integer.valueOf(deobjid), deName);
          CharObjidTable.get().addChar(deobjid, name);
        } else {
          del(deobjid);
        } 
        if (_reclanInfo)
          reclanInfo(clanid, deName); 
      } 
    } catch (SQLException e) {
      _log.error(e.getLocalizedMessage(), e);
    } finally {
      SQLUtil.close(rs);
      SQLUtil.close(pstm);
      SQLUtil.close(con);
    } 
  }
  
  private void del(int deobjid) {
    Connection con = null;
    PreparedStatement pstm = null;
    try {
      con = DatabaseFactoryLogin.get().getConnection();
      pstm = con.prepareStatement("DELETE FROM `de_name` WHERE `deobjid`=?");
      pstm.setInt(1, deobjid);
      pstm.execute();
    } catch (SQLException e) {
      _log.error(e.getLocalizedMessage(), e);
    } finally {
      SQLUtil.close(pstm);
      SQLUtil.close(con);
    } 
  }
  
  private void reclanInfo(int clanid, DeName deName) {
    DeClan deClan = DeClanTable.get().get(clanid);
    if (deClan != null) {
      deName.set_clanid(deClan.get_clan_id());
      deName.set_type(0);
      if (_random.nextBoolean()) {
        deName.set_sex(0);
      } else {
        deName.set_sex(1);
      } 
    } else {
      if (_random.nextInt(100) < 40) {
        Collection<DeClan> list = DeClanTable.get().getList();
        int i = _random.nextInt(list.size());
        int x = 0;
        Iterator<DeClan> iterator = list.iterator();
        while (iterator.hasNext()) {
          DeClan dxeClan = iterator.next();
          if (++x == i)
            deName.set_clanid(dxeClan.get_clan_id()); 
        } 
      } else {
        deName.set_clanid(0);
      } 
      int itype = _random.nextInt(6) + 1;
      deName.set_type(itype);
      if (_random.nextBoolean()) {
        deName.set_sex(0);
      } else {
        deName.set_sex(1);
      } 
    } 
    updata_deName(deName);
  }
  
  private void updata_deName(DeName deName) {
    Connection cn = null;
    PreparedStatement ps = null;
    try {
      cn = DatabaseFactoryLogin.get().getConnection();
      ps = cn.prepareStatement("UPDATE `de_name` SET `type`=?,`sex`=?,`clanid`=? WHERE `deobjid`=?");
      int i = 0;
      ps.setInt(++i, deName.get_type());
      ps.setInt(++i, deName.get_sex());
      ps.setInt(++i, deName.get_clanid());
      ps.setInt(++i, deName.get_deobjid());
      ps.execute();
    } catch (SQLException e) {
      _log.error(e.getLocalizedMessage(), e);
    } finally {
      SQLUtil.close(ps);
      SQLUtil.close(cn);
    } 
  }
  
  public DeName getDeName(int objid) {
    return _denames.get(Integer.valueOf(objid));
  }
  
  public DeName getDeName(String name) {
    return _denameList.get(name);
  }
  
  public Collection<DeName> getList() {
    return _denameList.values();
  }
  
  public DeName[] getDeNameList() {
    return (DeName[])_denameList.values().toArray((Object[])new DeName[_denameList.size()]);
  }
}
